home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / RTF / textflow.C < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  294 lines

  1. /* $Header: /usr/people/pcd/Src/RTF/RCS/textflow.C,v 1.1 92/11/23 12:58:56 pcd Exp Locker: pcd $
  2.  */
  3.  
  4. #include "textflow.h"
  5.  
  6. #include <string.h>
  7.  
  8. #include <assert.h>
  9. int debug_node = 0;
  10. #include "debug.h"
  11.  
  12. Node::Node(Node* par)
  13. {
  14.   parent_ = par;
  15.   left_ = right_ = 0;
  16.   left_child_ = right_child_ = 0;
  17. }
  18.  
  19. Node::Node(Node* par, Node* lef, Node* rt)
  20. {
  21.   Debug(node, ("Node::Node lef = %lx rt = %lx\n", lef, rt));
  22.   parent_ = par;
  23.   left_ = right_ = 0;
  24.   left_child_ = right_child_ = 0;
  25.   connect(lef, rt);
  26. }
  27.  
  28. void
  29. Node::connect(Node* lef, Node* rt)
  30. {
  31.   Debug(node, ("connect parent=%lx left=%lx this = %lx rt=%lx\n",
  32.      parent(), lef, this, rt));
  33.  
  34.   assert(lef == 0 || lef != rt);
  35.  
  36.   left_ = lef;
  37.  
  38.   if(lef){
  39.     Debug(node, ("this left: %x\n", lef));
  40.     right_ = lef->right();
  41.     lef->right_ = this;
  42.   }else{
  43.     Debug(node, ("this is left child\n"));
  44.     right_ = parent()->left_child();
  45.     parent_->left_child_ = this;
  46.   }
  47.  
  48.   if(right()){
  49.     Debug(node, ("this right: %x\n", right()));
  50.     right_->left_ = this;
  51.   }else
  52.     parent_->right_child_ = this;
  53.  
  54.   if(rt)
  55.     consume(rt);
  56. }
  57.  
  58. void
  59. Node::consume(Node* rt)
  60. {
  61.   Debug(node, ("this->right_child: %x\n", rt));
  62.   left_child_ = right_;
  63.   right_child_ = rt;
  64.   assert(left_child_->parent_ == right_child_->parent_);
  65.  
  66.   right_ = rt->right_;
  67.   if(right())
  68.     right_->left_ = this;
  69.   else
  70.     parent_->right_child_ = this;
  71.  
  72.   left_child_->left_ = 0;
  73.   right_child_->right_ = 0;
  74.  
  75.   Node* ch;
  76.   for(ch = left_child_; ch != right_child_; ch = ch->right_)
  77.     ch->parent_ = this;
  78.   right_child_->parent_ = this;
  79. }
  80.  
  81. Node::~Node()
  82. {
  83.   // ASSUME left_child_ == 0 ==> right_child_ == 0
  84.   Node* d = left_child_;
  85.   while(1){
  86.     delete d;
  87.     if(d == right_child_)
  88.       break;
  89.     else
  90.       d = d->right();
  91.   }
  92. }
  93.  
  94. void
  95. Node::disconnect()
  96. {
  97.   if(left() == 0 && right() == 0)
  98.     if(parent_ != this) // else root node
  99.       parent_->disconnect();
  100.   else{
  101.     if(left())
  102.       left_->right_ = right();
  103.     else
  104.       parent_->left_child_ = right();
  105.  
  106.     if(right())
  107.       right_->left_ = left();
  108.     else
  109.       parent_->right_child_ = right();
  110.   }
  111.   delete this;
  112. }
  113.  
  114.  
  115.  
  116. TextFlow::TextFlow(const Byte* d, Qty q)
  117. : Node(this)
  118. {
  119.   assert(q>0);
  120.   bytes_ = q;
  121.   data_ = new Byte[q];
  122.   memcpy(data_, d, q); //@# int!
  123.  
  124.   new TextFlow(*this, 0, data_, q);
  125. }
  126.  
  127. TextFlow::~TextFlow()
  128. {
  129.   if(parent() == this)
  130.     delete data_;
  131. }
  132.  
  133. TextFlow::TextFlow(TextFlow& par, TextFlow* left, const Byte* d, Qty q)
  134. : Node(&par, left, 0)
  135. {
  136.   data_ = (Byte*)d;
  137.   bytes_ = q;
  138. }
  139.  
  140.  
  141. TextFlow::TextFlow(TextFlow& p, TextPosition first, TextPosition last)
  142. : Node(&p, p.start_branch(first)->left(), 0)
  143. {
  144.   bytes_ = 0; // during end_branch
  145.   consume(p.end_branch(last));
  146.   data_ = (Byte*)p.data() + first;
  147.   bytes_ = last - first;
  148. }
  149.  
  150. Qty
  151. TextFlow::bytes_before() const
  152. {
  153.   Qty b = 0;
  154.   TextFlow* s = left();
  155.   while(s){
  156.     b += s->bytes();
  157.     s = s->left();
  158.   }
  159.   return b;
  160. }
  161.  
  162. Qty
  163. TextFlow::bytes_after() const
  164. {
  165.   Qty b = 0;
  166.   TextFlow* s = right();
  167.   while(s){
  168.     b += s->bytes();
  169.     s = s->right();
  170.   }
  171.   return b;
  172. }
  173.  
  174. TextFlow*
  175. TextFlow::start_branch(Qty offset)
  176. {
  177.   assert(offset < bytes());
  178.  
  179.   if(!left_child()){ // leaf
  180.     if(offset == 0)
  181.       return this;
  182.     else{ // split
  183.       Qty n = bytes() - offset;
  184.       bytes_ = offset;
  185.       return new TextFlow(*parent(), this, data() + bytes(), n);
  186.     }
  187.   }
  188.  
  189.   TextFlow* b;
  190.   for(b = left_child(); offset >= b->bytes(); b = b->right())
  191.     offset -= b->bytes();
  192.  
  193.   TextFlow* bb =  b->start_branch(offset);
  194.   if(this == bb->parent())
  195.     return bb;
  196.   else
  197.     return b;
  198. }
  199.  
  200. TextFlow*
  201. TextFlow::end_branch(Qty offset)
  202. {
  203.   assert(offset>0);
  204.  
  205.   if(!left_child()){ // leaf
  206.     if(offset == bytes())
  207.       return this;
  208.     else{ // split
  209.       Qty q = bytes() - offset;
  210.       bytes_ = offset;
  211.       new TextFlow(*parent(), this, data()+bytes(), q);
  212.       return this;
  213.     }
  214.   }
  215.  
  216.   TextFlow* b;
  217.   for(b = left_child(); offset > b->bytes(); b = b->right())
  218.     offset -= b->bytes();
  219.  
  220.   TextFlow* bb =  b->end_branch(offset);
  221.   if(this == bb->parent())
  222.     return bb;
  223.   else
  224.     return b;
  225. }
  226.  
  227. const TextFlow*
  228. TextFlow::subflow(TextPosition first, TextPosition last) const
  229. {
  230.   if(left_child() == 0)
  231.     return this;
  232.  
  233.   TextFlow* ret;
  234.   for(ret = left_child(); first >= ret->bytes(); ret = ret->right())
  235.     first -= ret->bytes(), last -= ret->bytes();
  236.  
  237.   if(last > ret->bytes())
  238.     return this;
  239.  
  240.   return ret;
  241. }
  242.  
  243.  
  244. const TextFlow*
  245. TextFlow::leaf(TextPosition first, TextPosition& move) const
  246. {
  247.   if(left_child() == 0)
  248.     return this;
  249.  
  250.   TextFlow* ret;
  251.   for(ret = left_child(); first >= ret->bytes(); ret = ret->right())
  252.     move -= ret->bytes(), first -= ret->bytes();
  253.  
  254.   return ret->leaf(first, move);
  255. }
  256.  
  257.  
  258. void
  259. TextFlow::line_shape(TextPosition pos, Extent& shape) const
  260. {
  261.   if(parent() != this){
  262.     parent()->line_shape(pos+bytes_before(), shape);
  263.     return;
  264.   }
  265.  
  266.   Extent empty(0,0,0,0,0);
  267.   shape = empty;
  268. }
  269.  
  270. Qty
  271. TextFlow::character_shape(TextPosition first, Qty qq,
  272.               Extent avail, Extent& used, int wrap) const
  273. {
  274.   if(parent() != this)
  275.     return parent()->character_shape(first+bytes_before(),
  276.                      qq,
  277.                      avail, used, wrap);
  278.  
  279.   used.x2 = -1; /* don't change justification */
  280.   used.x0 = used.y0 = used.y1 = 0;
  281.   return qq;
  282. }
  283.  
  284. void
  285. TextFlow::render(TextPosition first, Qty last, Point o) const
  286. {
  287.   if(parent() != this){
  288.     parent()->render(first+bytes_before(), last+bytes_before(), o);
  289.     return;
  290.   }
  291.   return;
  292. };
  293.  
  294.